package com.guass.nettyprotostuff.rpc.client;

import com.guass.nettyprotostuff.rpc.common.*;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;

/**
 * @author guass
 */
@Slf4j
@ChannelHandler.Sharable
public class NettyClientHandler extends CommonHandler{

    private IClient client;

    public NettyClientHandler(IClient client){
        this.client = client;
    }


    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, ModelMsg hotKeyMsg) throws Exception {
        handlerData(channelHandlerContext,hotKeyMsg);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("guass channelActive ");
        super.channelActive(ctx);

        Session session = Session.buildSession(ctx.channel());
        SessionManager.getInstance().put(session.getId(), session);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("guass inactive ");
        super.channelInactive(ctx);

        final String sessionId = ctx.channel().id().asLongText();
        Session session = SessionManager.getInstance().findBySessionId(sessionId);
        log.info("终端断开连接:{}", session);
        SessionManager.getInstance().removeBySessionId(sessionId);

        client.reConnect(client.getConnectInfo().getServerIp(),
                client.getConnectInfo().getPort());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.info("guass exceptionCaught {}",cause.getMessage());
        super.exceptionCaught(ctx, cause);

        final String sessionId = ctx.channel().id().asLongText();
        Session session = SessionManager.getInstance().findBySessionId(sessionId);
        log.info("终端断开连接:{}", session);
        SessionManager.getInstance().removeBySessionId(sessionId);

        client.reConnect(client.getConnectInfo().getServerIp(),
                client.getConnectInfo().getPort());
    }

    /**
     * channel不可写时关闭autoRead
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        if (!ctx.channel().isWritable()) {
            Channel channel = ctx.channel();
            channel.config().setAutoRead(false);
        }
    }

    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        if (channel.isWritable()) {
            channel.config().setAutoRead(true);
        }
    }



    @Override
    protected void handlerData(ChannelHandlerContext ctx, ModelMsg msg) {
        if (msg.getMessageType() == TypeData.PONG) {
            log.info("客户端收到心跳数据 {} ",msg);
        }else if(msg.getMessageType() == TypeData.CUSTOMER) {
            System.out.println(msg.getBody());
//            ModelMsg modelMsg = new ModelMsg();
//            modelMsg.setBody(msg.getBody() + " 收到!!!");
//            modelMsg.setMessageType(TypeData.CUSTOMER);
//
//
//            ctx.channel().writeAndFlush(modelMsg);
        }
    }

    @Override
    protected void handlerAllIdle(ChannelHandlerContext ctx) {
        super.handlerAllIdle(ctx);
        sendPingMsg(ctx);
    }
}
